//
//  HMStatusViewModel.swift
//  大深圳微博01
//
//  Created by shenzhenIOS on 16/4/12.
//  Copyright © 2016年 shenzhenIOS. All rights reserved.
//

import UIKit

import SDWebImage

class HMStatusViewModel: NSObject {
    
    /// 不要同时出现2个加载微博的请求
    /// 是否在加载微博数据
    private var loadStatusing: Bool = false

    // 单例
    static let sharedInstance: HMStatusViewModel = HMStatusViewModel()
    
    /// 加载本地数据
    private func loadLocalStatuses() {
        let path = NSBundle.mainBundle().pathForResource("statuses", ofType: "json")!
        let data = NSData(contentsOfFile: path)!
        
        // 函数抛出异常在函数后面有 throws,表示这段有可能会出现异常, 如果我们处理这个异常,程序是不会挂掉的,不处理就会挂掉
        // try!: 强制try, 有异常不处理,如果真的出现异常程序就挂了
        // do try catch: 处理异常,如果出现异常会走catch这个代码块,程序不会挂掉
        do {
            let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String: AnyObject]
            HMPrint("json: \(json)")
        } catch let error as NSError {
            HMPrint("json序列化异常: \(error)")
        }
    }
    
    /// 加载微博数据
    /// since_id: 下拉刷新获取最新微薄
    /// max_id: 上拉加载老的数据
    func loadStatus(since_id: Int64, max_id: Int64, loadStatusCallback: (statuses: [HMStatus]?, error: NSError?) -> ()) {
        
        // 1.先判断是否有人在加载微博数据
        if loadStatusing == true {
            // 有人在加载微博数据
            HMPrint("有人在加载微博数据")
            let error = HMNetworkErrorEnum.RepeatLoadStatus.error()
            loadStatusCallback(statuses: nil, error: error)
            return
        }
        
        // 将加载的状态改成ture,表示有人在加载微博
        loadStatusing = true
        
        print("since_id: \(since_id), max_id: \(max_id)")
        
        // 从DAL来获取数据
        HMStatusDAL.sharedDAL.loadStatus(since_id, max_id: max_id) { (statues, error) -> () in
            self.loadStatusing = false
            if error != nil {
                print("加载数据出错了: \(error)")
                loadStatusCallback(statuses: nil, error: error)
                
                return
            }
            
            // 加载到了微博数据
            // 定义数组来保存转好的微博模型
            var statusModels: [HMStatus] = []
            
            // 遍历每个字典
            for dict in statues! {
                // 字典转模型
                let status = HMStatus(dict: dict)
                
                // 将模型添加到数组里面
                statusModels.append(status)
            }
            
            // 02.缓存图片,将控制器传入的闭包cacheWebImage 的 loadStatusCallback
            self.cacheWebImage(statusModels, loadStatusCallback: loadStatusCallback)
        }
    }
    
    /// 缓存微博图片
    private func cacheWebImage(statuses: [HMStatus], loadStatusCallback: (statuses: [HMStatus]?, error: NSError?) -> ()) {
        // 创建任务组
        let group = dispatch_group_create()
        
        // 判断每个模型,看看是不是有图片要下载
        for status in statuses {
            var downloadURLs: [NSURL]?
            
            downloadURLs = status.storePicutreURLs
            
            // 如果原创没有图片要下载,看被转发微博是不是有图片要下载
            if downloadURLs == nil {
                downloadURLs = status.retweeted_status?.storePicutreURLs
            }
            
            // 看看是否有图片要下载
            if let urls = downloadURLs {
                // 只有一张图片的时候才需要提前下载.多张图片的时候可以等到tableView显示出来的时候在去下载也可以,这样可以提高微博加载速速
                if urls.count == 1 {
                    // 获取一张要下载的图片的url地址
                    let url = urls.first!
//                for url in urls {
                    // 使用SDWebImage去下载图片
                    // options: [SDWebImageOptions.AvoidAutoSetImage, SDWebImageOptions.CacheMemoryOnly]
                    // 异步任务之前进入组
                    dispatch_group_enter(group)
                    // SDWebImage异步下载图片
                    SDWebImageManager.sharedManager().downloadImageWithURL(url, options: [], progress: nil, completed: { (image, error, _, _, _) -> Void in // 异步任务完成会回调这个闭包
                        dispatch_group_leave(group)
                        
                        if error != nil {
                            HMPrint("下载图片失败: \(url)")
                            return
                        }
                        
//                        HMPrint("下载图片完成: \(url)")
                    })
                }
            }
        }
        
        // 监听所有微博下载图片完成
        dispatch_group_notify(group, dispatch_get_main_queue()) { () -> Void in
            HMPrint("SD下载所有图片完成")
            // SD下载所有图片完成,回调控制器,控制器会拿到数据,然后刷新界面
            loadStatusCallback(statuses: statuses, error: nil)
        }
    }
    
    // MARK: - 发微博
    /// text: 要发布微博的文本内容
    func sendStatus(text: String, image: UIImage?, sendStatusCallback: (error: NSError?) -> ()) {
        guard let access_token = HMUserAccountViewModel.sharedInstance.userAccount?.access_token else {
            print("access_token为空")
            
            let error = HMNetworkErrorEnum.AccessTokenEmpty.error()
            sendStatusCallback(error: error)
            return
        }
        
        // 参数
        let parameters = [
            "access_token": access_token,
            "status": text
        ]
        
        if image == nil {   // 纯文本微博
            // url
            let urlString = "https://api.weibo.com/2/statuses/update.json"
            
            
            // 发送请求
            HMNetworkTool.sharedInstance.POST(urlString, parameters: parameters, progress: nil, success: { (_, responseObject) -> Void in
                // 发布成功了
                sendStatusCallback(error: nil)
                }) { (_, error) -> Void in
                    // 失败了
                    sendStatusCallback(error: error)
            }
        } else {    // 带图片的微博
            // url
            let urlString = "https://upload.api.weibo.com/2/statuses/upload.json"
            
            // 发送请求
            HMNetworkTool.sharedInstance.POST(urlString, parameters: parameters, constructingBodyWithBlock: { (formdata) -> Void in
                let data = UIImagePNGRepresentation(image!)!
                
                // 上传图片
                // data: NSData: 要上传的二进制
                // name: API文档指定的上传参数
                // fileName: 上传后保存在服务器的名称,看API，如果API没有指定,可以不写
                // mimeType: 上传二进制的类型 image,  image/png, image/jpeg, image/gif
                formdata.appendPartWithFileData(data, name: "pic", fileName: "", mimeType: "image/png")
//                formdata.appendPartWithFileData(data, name: "pic1", fileName: "", mimeType: "image/png")
//                formdata.appendPartWithFileData(data, name: "pic2", fileName: "", mimeType: "image/png")
                }, progress: nil, success: { (_, responseObject) -> Void in
                     // 发布成功了
                    sendStatusCallback(error: nil)
                }, failure: { (_, error) -> Void in
                    // 失败了
                    sendStatusCallback(error: error)
            })
        }
    }
}
